from pathlib import Path
import json
import random
from re import T
import string
import time
import uuid
import os
import sys
from dataclasses import dataclass
from typing import Dict, Tuple, Optional

# 简化导入方式
try:
    # 先尝试直接导入
    from device_info_api import DeviceInfoApi, DeviceInfoRequest
    from laste_device_id_gen_and_verify import create_device_id
except ImportError:
    # 如果直接导入失败，尝试从当前目录导入
    from .device_info_api import DeviceInfoApi, DeviceInfoRequest
    from .laste_device_id_gen_and_verify import create_device_id


def get_devices_dir() -> str:
    """获取设备信息保存目录
    
    根据是否打包决定使用不同的目录路径
    
    Returns:
        str: 设备信息保存目录的路径
    """
    # 判断是否是打包环境
    is_packaged = getattr(sys, 'frozen', False)
    
    if is_packaged:
        # 打包环境下，使用可执行文件所在目录
        base_dir = os.path.dirname(sys.executable)
    else:
        # 开发环境下，使用项目根目录
        base_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    
    # 创建 data/devices 目录
    devices_dir = os.path.join(base_dir, "data", "devices")
    
    # 确保目录存在
    os.makedirs(devices_dir, exist_ok=True)
    
    return devices_dir


def generate_android_id() -> str:
    """生成Android ID
    
    Android ID通常是16个字符的十六进制字符串
    
    Returns:
        str: 生成的Android ID
    """
    # 生成16个十六进制字符
    hex_chars = '0123456789abcdef'
    android_id = ''.join(random.choice(hex_chars) for _ in range(16))
    return android_id


def generate_device_id_from_android_id(android_id: str = None) -> str:
    """根据Android ID生成设备ID
    
    Args:
        android_id: Android ID，如果不提供则自动生成
        
    Returns:
        str: 生成的设备ID (UTDID)
    """
    # 如果未提供Android ID，则生成一个
    if not android_id:
        android_id = generate_android_id()
    
    # 使用laste_device_id_gen_and_verify.py中的create_device_id函数生成设备ID
    device_id = create_device_id(android_id)
    
    print(f"生成的设备ID: {device_id}")
    return device_id


def get_device_fingerprint(android_id: str = None, device_id: str = None) -> Tuple[str, str, str]:
    """获取设备指纹
    
    Args:
        android_id: Android ID，如果不提供则自动生成
        device_id: 设备ID，如果不提供则根据Android ID生成
        
    Returns:
        Tuple[str, str, str]: (Android ID, 设备ID, UK值)
    """
    # 1. 生成Android ID（如果未提供）
    if not android_id:
        android_id = generate_android_id()
    print(f"使用的Android ID: {android_id}")
    
    # 2. 根据Android ID生成设备ID（如果未提供）
    if not device_id:
        device_id = generate_device_id_from_android_id(android_id)
    print(f"使用的设备ID: {device_id}")
    
    # 3. 调用设备信息API获取UK值
    try:
        # 创建设备信息API实例
        device_info_api = DeviceInfoApi(
            device_token=device_id,
            device_id=device_id,
            auth_token="",  # 首次调用不需要授权令牌
            uk=""  # 首次调用不需要UK值
        )
        
        # 创建设备信息请求对象，设置Android ID
        request = DeviceInfoRequest.create_default(
            device_id=device_id,
            uk="",
            user_id=0,
            android_id=android_id
        )
        
        print("正在调用设备信息API获取UK值...")
        # 发送设备信息上报请求
        response = device_info_api.report_device_info(request)
        
        # 检查响应状态码
        if response.code == 0 and response.data and 'uk' in response.data:
            uk = response.data['uk']
            print(f"获取UK值成功: {uk}")
            return android_id, device_id, uk
        else:
            print(f"获取UK值失败: {response.msg}")
            return android_id, device_id, ""
    except Exception as e:
        print(f"调用设备信息API异常: {e}")
        return android_id, device_id, ""


def save_device_info(android_id: str, device_id: str, uk: str, mobile: str, file_path: str = None):
    """保存设备信息到文件
    
    Args:
        android_id: Android ID
        device_id: 设备ID
        uk: UK值
        mobile: 手机号码，用于生成文件名
        file_path: 保存的文件路径，如果为None则使用默认路径
    """
    data = {
        "android_id": android_id,
        "device_id": device_id,
        "uk": uk,
        "mobile": mobile,
        "timestamp": int(time.time()),
        "create_time": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    }
    
    try:
        # 如果未指定文件路径，则使用默认路径
        if file_path is None:
            devices_dir = get_devices_dir()
            file_path = os.path.join(devices_dir, f"{mobile}_deviceinfo.json")
        
        # 确保目录存在
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        with open(file_path, 'w') as f:
            json.dump(data, f, indent=4)
        print(f"设备信息已保存到: {file_path}")
    except Exception as e:
        print(f"保存设备信息失败: {e}")


def load_device_info(mobile: str = None, file_path: str = None) -> Dict[str, str]:
    """从文件加载设备信息
    
    Args:
        mobile: 手机号码，用于生成文件名
        file_path: 文件路径，如果为None则使用默认路径
        
    Returns:
        Dict[str, str]: 包含android_id、device_id和uk的字典
    """
    try:
        # 如果未指定文件路径，则使用默认路径
        if file_path is None and mobile:
            devices_dir = get_devices_dir()
            file_path = os.path.join(devices_dir, f"{mobile}_deviceinfo.json")
        
        if file_path and Path(file_path).exists():
            with open(file_path, 'r') as f:
                data = json.load(f)
                print(f"从文件加载设备信息: {file_path}")
                return data
    except Exception as e:
        print(f"加载设备信息失败: {e}")
    
    return {"android_id": "", "device_id": "", "uk": "", "mobile": ""}


def get_device_fingerprint_info(generate_new: bool = True, file_path: str = None, mobile: str = None) -> Tuple[str, str, str]:
    """获取设备指纹信息的主方法
    
    Args:
        generate_new: 是否强制生成新的设备信息，默认为False
        file_path: 设备信息文件路径，默认为None
        mobile: 手机号码，用于生成文件名，默认为None
        
    Returns:
        Tuple[str, str, str]: (Android ID, 设备ID, UK值)，如果获取失败则返回(None, None, None)
    """
    print("=" * 50)
    print("设备指纹获取工具")
    print("=" * 50)
    mobile = mobile
    # 如果不强制生成新的，则尝试从文件加载
    if not generate_new:
        # 检查是否有保存的设备信息
        saved_info = load_device_info(mobile=mobile, file_path=file_path)
        
        if saved_info.get("android_id") and saved_info.get("device_id") and saved_info.get("uk"):
            print("\n找到已保存的设备信息:")
            print(f"Android ID: {saved_info['android_id']}")
            print(f"设备ID: {saved_info['device_id']}")
            print(f"UK值: {saved_info['uk']}")
            print(f"创建时间: {saved_info.get('create_time', '未知')}")
            
            return saved_info['android_id'], saved_info['device_id'], saved_info['uk']
    
    # 生成新的设备信息
    print("\n生成新的设备信息...")
    android_id, device_id, uk = get_device_fingerprint()
    
    if uk:
        # 保存设备信息
        save_device_info(android_id, device_id, uk, mobile, file_path)
        
        print("\n设备指纹获取成功:")
        print(f"Android ID: {android_id}")
        print(f"设备ID: {device_id}")
        print(f"UK值: {uk}")
        return android_id, device_id, uk
    else:
        print("\n设备指纹获取失败")
        return None, None, None


def main():
    """测试程序，展示如何使用get_device_fingerprint_info方法"""
    print("=" * 50)
    print("设备指纹获取工具测试程序")
    print("=" * 50)
    mobile = "13186793939"  # 替换为实际手机号
    # 测试场景1: 从文件加载设备信息（如果有）
    print("\n测试场景1: 从文件加载设备信息")
    print("-" * 30)
    android_id1, device_id1, uk1 = get_device_fingerprint_info(generate_new=False, mobile=mobile)
    print(f"测试场景1结果: Android ID: {android_id1}, 设备ID: {device_id1}, UK值: {uk1[:10]}...")
    
    # 测试场景2: 强制生成新的设备信息
    print("\n测试场景2: 强制生成新的设备信息")
    print("-" * 30)
    android_id2, device_id2, uk2 = get_device_fingerprint_info(generate_new=True, mobile=mobile)
    print(f"测试场景2结果: Android ID: {android_id2}, 设备ID: {device_id2}, UK值: {uk2[:10]}...")
    
    # 测试场景3: 使用自定义文件路径
    custom_path = "custom_device_info.json"
    print(f"\n测试场景3: 使用自定义文件路径 ({custom_path})")
    print("-" * 30)
    android_id3, device_id3, uk3 = get_device_fingerprint_info(file_path=custom_path, mobile=mobile)
    print(f"测试场景3结果: Android ID: {android_id3}, 设备ID: {device_id3}, UK值: {uk3[:10]}...")
    
    print("\n" + "=" * 50)
    print("测试完成")
    print("=" * 50)


if __name__ == "__main__":
    main()
